package ee.ut.cs.mc.madp.p2pdivider;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.util.Log;

/**
 * Class for superawesome utility methods!
 * 
 * @author Kaarel Jõgeva
 */
public class Utils {

    public static final String TAG = "Utility";
    public static final String ARP_CACHE = "/proc/net/arp";

    public static <I extends InputStream, O extends OutputStream> boolean copyFile(I input, O output) {
        byte buf[] = new byte[1024];
        int len;
        try {
            while ((len = input.read(buf)) != -1) {
                output.write(buf, 0, len);
            }
        } catch (IOException e) {
            Log.d(TAG, e.toString());
            return false;
        }
        return true;
    }

    @Deprecated
    public static String getIPFromMac(String MAC) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(ARP_CACHE));
            String line;
            while ((line = br.readLine()) != null) {

                String[] splitted = line.split(" +");
                if (splitted != null && splitted.length >= 4) {
                    // Basic sanity check
                    String device = splitted[5];
                    if (device.matches(".*p2p.*")) {
                        String mac = splitted[3];
                        if (mac.startsWith(MAC.substring(0, 10))) { // FIXME 06:46:65:23:3e:d4 vs 06:46:65:23:be:d4 Is ARP chace outdated?
                            return splitted[0];
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static Bitmap decodeSampledBitmapFromResource(File image, int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        InputStream is = null;
        try {
            is = new FileInputStream(image);
            BitmapFactory.decodeStream(is, null, options);
            int origW = options.outWidth;
            int origH = options.outHeight;

            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            is = new FileInputStream(image);

            return BitmapRegionDecoder.newInstance(is, false).decodeRegion(new Rect(0, 0, origW, origH / 2), options);

            // Bitmap decodeStream = BitmapFactory.decodeStream(is, null, options);
            // return decodeStream;

        } catch (Exception e) {
            Log.e(TAG, "Error decoding sampled section of image!", e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    // Ignore
                }
            }
        }
        return null;
    }

    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            if (width > height) {
                inSampleSize = Math.round((float) height / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) width / (float) reqWidth);
            }
        }
        return inSampleSize;
    }

    public static void closeQuietly(Closeable... closeable) {
        for (Closeable c : closeable) {
            if (c != null) {
                try {
                    c.close();
                } catch (Exception e) {
                    // It's already closed
                }
            }
        }
    }
}
